from rest_framework import mixins
from rest_framework.decorators import action

from framework.response import response

from framework import Code


class IsValidMixin:

    def serializer_is_valid(self, request, *args, **kwargs):
        data = request.data
        serializer_class = self.serializer_class
        serializer = serializer_class(data=data)
        serializer.is_valid(raise_exception=True)
        errors = serializer.errors
        if errors:
            return response(code=Code.C_4_0, message=errors)


class CreateModelMixin(mixins.CreateModelMixin):
    """
    创建单挑数据
    """

    def create(self, request, *args, **kwargs):
        super().create(request, *args, **kwargs)
        return response(code=Code.C_2_1)


class ListModelMixin(mixins.ListModelMixin):
    """
    查多个数据
    """

    def list(self, request, *args, **kwargs):
        """查多个"""
        ret = super().list(request, *args, **kwargs)
        return response(data=ret.data)


class RetrieveModelMixin(mixins.RetrieveModelMixin):
    """
    查单条数据
    """

    def retrieve(self, request, *args, **kwargs):
        ret = super().retrieve(request, *args, **kwargs)
        return response(data=ret.data)


class UpdateModelMixin(mixins.UpdateModelMixin):
    """
    修改单条数据
    """

    def update(self, request, *args, **kwargs):
        """修改"""
        super().update(request, *args, **kwargs)
        return response(code=Code.C_2_2)


class DestroyModelMixin(mixins.DestroyModelMixin):
    """
    修改 destroy 响应 逻辑删除
    """

    def destroy(self, request, *args, **kwargs):
        """删除"""

        super().destroy(request, *args, **kwargs)
        return response(code=Code.C_2_3)

    def perform_destroy(self, instance):
        """
        存在逻辑删除，逻辑删除，否则直接删除
        """
        try:
            instance.is_deleted = True
        except AttributeError:
            instance.delete()
        else:
            instance.save()


class DeleteBatchMixin:
    """
    注意 依赖 view sets
    批量删除同一个model多行。删除字段 deleted_field 0 未删除 1 已删除
    method:
        + /delete_batch/
    """

    deleted_field = 'is_deleted'

    @action(methods=['POST'], detail=False)
    def delete_batch(self, request):
        ids = request.data.get('ids', None)
        if ids:
            self.queryset.filter(id__in=ids).update(**{self.deleted_field: 1})
        else:
            return response(code=Code.C_4_0, message='ids 为必传项')
        return response(code=Code.C_2_3)


class PuBatchMixin:
    """
    依赖 view sets
    批量修改同一个model多行，相同的条件
    method:
        + /put_batch/
    """

    @action(methods=['POST'], detail=False)
    def put_batch(self, request):
        data = request.data
        ids = data.pop('ids', None)
        if ids:
            self.queryset.filter(id__in=ids).update(**data)
        else:
            return response(code=Code.C_4_0, message='ids 为必传项')
        return response()


class SelectMixin:
    """
    依赖 view sets
    function:
        select
        获取 下拉框列表
    method:
        + /select/
    """
    select_fields = ('id', 'name')
    select_order_by = True
    order_by_field = 'id'

    @action(methods=['GET'], detail=False)
    def select(self, request):
        if self.select_order_by:
            queryset = self.queryset.values(*self.select_fields).order_by(self.order_by_field)
        else:
            queryset = self.queryset.values(*self.select_fields)
        return response(data=list(queryset))
